﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GabageFactory.Models;

namespace GabageFactory.Controllers
{
    [Authorize]
    public class HistoryController : BaseController
    {
        StackReposity stackReposity = new StackReposity();

        StackWaterReposity stackWaterReposity = new StackWaterReposity();

        PoolReposity poolReposity = new PoolReposity();

        StackBackWaterReposity stackBackWaterReposity = new StackBackWaterReposity();

        DikeSettleOffsetReposity dikeSettleOffsetReposity = new DikeSettleOffsetReposity();

        StackArdealiteReposity stackArdealiteReposity = new StackArdealiteReposity();

        TailingpondBackWaterReposity tailingpondBackWaterReposity = new TailingpondBackWaterReposity();

        TailingpondDailyWaterReposity tailingpondDailyWaterReposity = new TailingpondDailyWaterReposity();

        TailingpondDitchReposity tailingpondDitchReposity = new TailingpondDitchReposity();

        TailingpondFilldamReposity tailingpondFilldamReposity = new TailingpondFilldamReposity();

        FactoryWeatherReposity factoryWeatherReposity = new FactoryWeatherReposity();
        //
        // GET: /Record/StackWater/5
        public ActionResult StackWater(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;
            
            IEnumerable<Return_Water_Pond_Base_Info> pools = poolReposity.ListPools(id);
            int poolNum = pools.Count();
            if (poolNum <= 0)
            {
                poolNum = 1;
            }

            stack_pool_daily_water_info[] poolWaterInfoArray = new stack_pool_daily_water_info[poolNum];
            IEnumerable<stack_pool_daily_water_info> poolWaterInfos = stackWaterReposity.GetDailyPoolWaterInfo(id, now);

            for (int i = 0; i < poolNum; i++)
            {
                if (poolWaterInfos != null && i < poolWaterInfos.Count())
                {
                    poolWaterInfoArray[i] = poolWaterInfos.ElementAt(i);
                }
                else
                {
                    stack_pool_daily_water_info poolDailyWaterInfo = new stack_pool_daily_water_info();
                    poolDailyWaterInfo.stack_id = id;
                    poolDailyWaterInfo.pool_no = i;
                    poolDailyWaterInfo.date = now.Date;
                    poolWaterInfoArray[i] = poolDailyWaterInfo;
                }
            }
            ViewData["poolWaterInfos"] = poolWaterInfoArray;

            stack_daily_water_info waterInfo = stackWaterReposity.GetDailyWaterInfo(id, now);
            if (waterInfo == null)
            {
                waterInfo = new stack_daily_water_info();
                waterInfo.stack_id = id;
                waterInfo.date = now.Date;
            }

            ViewData["success"] = false;
            return View(waterInfo);
        }

        [HttpPost]
        public ActionResult StackWater(stack_daily_water_info dailyWaterInfo, FormCollection collection)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            DateTime now = DateTime.Now;
            int id = dailyWaterInfo.stack_id;
            ViewData["id"] = id;

            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            dailyWaterInfo.date = now.Date;
            stack_daily_water_info oldDailyWaterInfo = stackWaterReposity.GetDailyWaterInfo(id, now);
            if (oldDailyWaterInfo != null)
            {
                stackWaterReposity.DeleteWaterInfo(oldDailyWaterInfo);
            }
            stackWaterReposity.CreateWaterInfo(dailyWaterInfo);

            
            stackWaterReposity.DeleteDailyPoolWaterInfos(id, now);
            int poolNum = parseInt(collection.Get("poolNum"));
            for (int i = 1; i <= poolNum; i++)
            {
                float poolWaterLevel = parseFloat(collection.Get("pool_water_level" + i));
                float poolWaterPH = parseFloat(collection.Get("pool_water_ph" + i));
                stack_pool_daily_water_info poolDailyWaterInfo = new stack_pool_daily_water_info();
                poolDailyWaterInfo.stack_id = id;
                poolDailyWaterInfo.date = now.Date;
                poolDailyWaterInfo.pool_no = i;
                poolDailyWaterInfo.pool_water_level = poolWaterLevel;
                poolDailyWaterInfo.pool_water_ph = poolWaterPH;
                stackWaterReposity.CreateDailyPoolWaterInfo(poolDailyWaterInfo);
            }

            stack_pool_daily_water_info[] poolWaterInfoArray = new stack_pool_daily_water_info[poolNum];
            IEnumerable<stack_pool_daily_water_info> poolWaterInfos = stackWaterReposity.GetDailyPoolWaterInfo(id, now);

            IEnumerable<Return_Water_Pond_Base_Info> pools = poolReposity.ListPools(id);
            poolNum = pools.Count();
            if (poolNum <= 0)
            {
                poolNum = 1;
            }
            for (int i = 0; i < poolNum; i++)
            {
                if (poolWaterInfos != null && i < poolWaterInfos.Count())
                {
                    poolWaterInfoArray[i] = poolWaterInfos.ElementAt(i);
                }
                else
                {
                    stack_pool_daily_water_info poolDailyWaterInfo = new stack_pool_daily_water_info();
                    poolDailyWaterInfo.stack_id = id;
                    poolDailyWaterInfo.pool_no = i;
                    poolDailyWaterInfo.date = now.Date;
                    poolWaterInfoArray[i] = poolDailyWaterInfo;
                }
            }
            ViewData["poolWaterInfos"] = poolWaterInfoArray;


            ViewData["success"] = true;
            return View(dailyWaterInfo);
        }

        //
        // GET: /Record/BackWater/5
        public ActionResult BackWater(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            Stack stack = stackReposity.GetStackById(id);

            if (stack != null)
            {
                ViewData["flowInPic"] = stack.FlowInPic;
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;

            stack_backwater_info backWaterInfo = stackBackWaterReposity.GetDailyBackWaterInfo(id, now);
            if (backWaterInfo == null)
            {
                backWaterInfo = new stack_backwater_info();
                backWaterInfo.stack_id = id;
                backWaterInfo.date = now.Date;
                backWaterInfo.siphon_caliber = 500;
            }
            
            ViewData["success"] = false;
            return View(backWaterInfo);
        }

        [HttpPost]
        public ActionResult BackWater(stack_backwater_info backWaterInfo)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = backWaterInfo.stack_id;
            ViewData["id"] = id;

            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            backWaterInfo.date = now.Date;

            stack_backwater_info oldBackWaterInfo = stackBackWaterReposity.GetDailyBackWaterInfo(id, now);
            if (oldBackWaterInfo != null)
            {
                stackBackWaterReposity.DeleteWaterInfo(oldBackWaterInfo);
            }
            stackBackWaterReposity.CreateBackWaterInfo(backWaterInfo);
            ViewData["success"] = true;

            Stack stack = stackReposity.GetStackById(id);

            if (stack != null)
            {
                ViewData["flowInPic"] = stack.FlowInPic;
            }
            return View(backWaterInfo);
        }

        //
        // GET: /Record/Settle/5
        public ActionResult Settle(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;
            DateTime monthDate = new DateTime(now.Year, now.Month, 1);

            stack_settle_offset settleOffset = dikeSettleOffsetReposity.GetDikeSettleInfo(id, now);
            if (settleOffset == null)
            {
                settleOffset = new stack_settle_offset();
                settleOffset.stack_id = id;
                settleOffset.date = monthDate;
            }

            IEnumerable<Return_Water_Pond_Base_Info> pools = poolReposity.ListPools(id);
            int poolNum = pools.Count();
            if (poolNum <= 0)
            {
                poolNum = 1;
            }

            stack_settle_offset_pool_info[] offsetPoolInfoArray = new stack_settle_offset_pool_info[poolNum];
            IEnumerable<stack_settle_offset_pool_info> offsetPoolInfos = dikeSettleOffsetReposity.GetMonthSettleOffsetPoolInfo(id, now);

            for (int i = 0; i < poolNum; i++)
            {
                if (offsetPoolInfos != null && i < offsetPoolInfos.Count())
                {
                    offsetPoolInfoArray[i] = offsetPoolInfos.ElementAt(i);
                }
                else
                {
                    stack_settle_offset_pool_info offsetPoolInfo = new stack_settle_offset_pool_info();
                    offsetPoolInfo.stack_id = id;
                    offsetPoolInfo.pool_no = i;
                    offsetPoolInfo.date = monthDate.Date;
                    offsetPoolInfoArray[i] = offsetPoolInfo;
                }
            }
            ViewData["offsetPoolInfos"] = offsetPoolInfoArray;


            ViewData["success"] = false;
            return View(settleOffset);
        }

        [HttpPost]
        public ActionResult Settle(stack_settle_offset settleOffset, FormCollection collection)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = settleOffset.stack_id;
            ViewData["id"] = id;

            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            DateTime monthDate = new DateTime(now.Year, now.Month, 1);

            settleOffset.date = monthDate;
            stack_settle_offset oldSettleOffset = dikeSettleOffsetReposity.GetDikeSettleInfo(id, now);
            if (oldSettleOffset != null)
            {
                dikeSettleOffsetReposity.DeleteDikeSettleInfo(oldSettleOffset);
            }
            dikeSettleOffsetReposity.CreateDikeSettleInfo(settleOffset);


            dikeSettleOffsetReposity.DeleteSettleOffsetPoolInfos(id, monthDate);
            int poolNum = parseInt(collection.Get("poolNum"));
            for (int i = 1; i <= poolNum; i++)
            {
                float ditchEl = parseFloat(collection.Get("ditch_El" + i));
                stack_settle_offset_pool_info poolInfo = new stack_settle_offset_pool_info();
                poolInfo.stack_id = id;
                poolInfo.date = monthDate;
                poolInfo.pool_no = i;
                poolInfo.ditch_El = ditchEl;
                dikeSettleOffsetReposity.CreateSettleOffsetPoolInfo(poolInfo);
            }

            stack_settle_offset_pool_info[] offsetPoolInfoArray = new stack_settle_offset_pool_info[poolNum];
            IEnumerable<stack_settle_offset_pool_info> offsetPoolInfos = dikeSettleOffsetReposity.GetMonthSettleOffsetPoolInfo(id, now);

            IEnumerable<Return_Water_Pond_Base_Info> pools = poolReposity.ListPools(id);
            poolNum = pools.Count();
            if (poolNum <= 0)
            {
                poolNum = 1;
            }
            for (int i = 0; i < poolNum; i++)
            {
                if (offsetPoolInfos != null && i < offsetPoolInfos.Count())
                {
                    offsetPoolInfoArray[i] = offsetPoolInfos.ElementAt(i);
                }
                else
                {
                    stack_settle_offset_pool_info offsetPoolInfo = new stack_settle_offset_pool_info();
                    offsetPoolInfo.stack_id = id;
                    offsetPoolInfo.pool_no = i;
                    offsetPoolInfo.date = monthDate.Date;
                    offsetPoolInfoArray[i] = offsetPoolInfo;
                }
            }
            ViewData["offsetPoolInfos"] = offsetPoolInfoArray;

            ViewData["success"] = true;
            return View(settleOffset);
        }


        //
        // GET: /Record/Ardealite/5
        public ActionResult Ardealite(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;

            stack_ardealite_ditch dailyArdealiteDitchInfo = stackArdealiteReposity.GetDailyArdealiteDitchInfo(id, now);
            if (dailyArdealiteDitchInfo == null)
            {
                dailyArdealiteDitchInfo = new stack_ardealite_ditch();
                dailyArdealiteDitchInfo.stack_id = id;
                dailyArdealiteDitchInfo.date = now.Date;
                dailyArdealiteDitchInfo.dike_downstream_slope_rate = "1:2.5";
            }

            ViewData["success"] = false;
            return View(dailyArdealiteDitchInfo);
        }

        [HttpPost]
        public ActionResult Ardealite(stack_ardealite_ditch dailyArdealiteDitchInfo)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = dailyArdealiteDitchInfo.stack_id;
            ViewData["id"] = id;

            if (!CanEditStack(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            dailyArdealiteDitchInfo.date = now.Date;

            stack_ardealite_ditch oldDailyArdealiteDitchInfo = stackArdealiteReposity.GetDailyArdealiteDitchInfo(id, now);
            if (oldDailyArdealiteDitchInfo != null)
            {
                stackArdealiteReposity.DeleteArdealiteDitchInfo(oldDailyArdealiteDitchInfo);
            }
            stackArdealiteReposity.CreateArdealiteDitchInfo(dailyArdealiteDitchInfo);
            ViewData["success"] = true;
            return View(dailyArdealiteDitchInfo);
        }


        //
        // GET: /Record/TailingpondWater/5
        public ActionResult TailingpondWater(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;

            tailingpond_daily_water_info dailyWaterInfo = tailingpondDailyWaterReposity.GetDailyWaterInfo(id, now);
            if (dailyWaterInfo == null)
            {
                dailyWaterInfo = new tailingpond_daily_water_info();
                dailyWaterInfo.tailingpond_id = id;
                dailyWaterInfo.date = now.Date;
            }

            ViewData["success"] = false;
            return View(dailyWaterInfo);
        }

        [HttpPost]
        public ActionResult TailingpondWater(tailingpond_daily_water_info dailyWaterInfo)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = dailyWaterInfo.tailingpond_id;
            ViewData["id"] = id;

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            dailyWaterInfo.date = now.Date;

            tailingpond_daily_water_info oldDailyWaterInfo = tailingpondDailyWaterReposity.GetDailyWaterInfo(id, now);
            if (oldDailyWaterInfo != null)
            {
                tailingpondDailyWaterReposity.DeleteDailyWaterInfo(oldDailyWaterInfo);
            }
            tailingpondDailyWaterReposity.CreateDailyWaterInfo(dailyWaterInfo);
            ViewData["success"] = true;
            return View(dailyWaterInfo);
        }

        //
        // GET: /Record/TailingpondBackWater/5
        public ActionResult TailingpondBackWater(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;

            tailingpond_backwater_info backWaterInfo = tailingpondBackWaterReposity.GetDailyBackwaterInfo(id, now);
            if (backWaterInfo == null)
            {
                backWaterInfo = new tailingpond_backwater_info();
                backWaterInfo.tailingpond_id = id;
                backWaterInfo.date = now.Date;
            }

            ViewData["success"] = false;
            return View(backWaterInfo);
        }

        [HttpPost]
        public ActionResult TailingpondBackWater(tailingpond_backwater_info backWaterInfo)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = backWaterInfo.tailingpond_id;
            ViewData["id"] = id;

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            backWaterInfo.date = now.Date;

            tailingpond_backwater_info oldBackWaterInfo = tailingpondBackWaterReposity.GetDailyBackwaterInfo(id, now);
            if (oldBackWaterInfo != null)
            {
                tailingpondBackWaterReposity.DeleteBackWaterInfo(oldBackWaterInfo);
            }
            tailingpondBackWaterReposity.CreateBackWaterInfo(backWaterInfo);
            ViewData["success"] = true;
            return View(backWaterInfo);
        }

        //
        // GET: /Record/TailingpondDitch/5
        public ActionResult TailingpondDitch(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;

            tailingpond_daily_ditch_info ditchInfo = tailingpondDitchReposity.GetDailyDitchInfo(id, now);
            if (ditchInfo == null)
            {
                ditchInfo = new tailingpond_daily_ditch_info();
                ditchInfo.tailingpond_id = id;
                ditchInfo.date = now.Date;
            }

            ViewData["success"] = false;
            return View(ditchInfo);
        }

        [HttpPost]
        public ActionResult TailingpondDitch(tailingpond_daily_ditch_info ditchInfo)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = ditchInfo.tailingpond_id;
            ViewData["id"] = id;

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            ditchInfo.date = now.Date;

            tailingpond_daily_ditch_info oldDitchInfo = tailingpondDitchReposity.GetDailyDitchInfo(id, now);
            if (oldDitchInfo != null)
            {
                tailingpondDitchReposity.DeleteDailyDitch(oldDitchInfo);
            }
            tailingpondDitchReposity.CreateDailyDitch(ditchInfo);
            ViewData["success"] = true;
            return View(ditchInfo);
        }

        //
        // GET: /Record/TailingpondFilldam/5
        public ActionResult TailingpondFilldam(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;

            tailingpond_daily_filldam_info filldamInfo = tailingpondFilldamReposity.GetDailyFilldamInfo(id, now);
            if (filldamInfo == null)
            {
                filldamInfo = new tailingpond_daily_filldam_info();
                filldamInfo.tailingpond_id = id;
                filldamInfo.date = now.Date;
            }

            ViewData["success"] = false;
            return View(filldamInfo);
        }

        [HttpPost]
        public ActionResult TailingpondFilldam(tailingpond_daily_filldam_info filldamInfo)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = filldamInfo.tailingpond_id;
            ViewData["id"] = id;

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            filldamInfo.date = now.Date;

            tailingpond_daily_filldam_info oldFilldamInfo = tailingpondFilldamReposity.GetDailyFilldamInfo(id, now);
            if (oldFilldamInfo != null)
            {
                tailingpondFilldamReposity.DeleteFilldamInfo(oldFilldamInfo);
            }
            tailingpondFilldamReposity.CreateFilldamInfo(filldamInfo);
            ViewData["success"] = true;
            return View(filldamInfo);
        }


        //
        // GET: /Record/TailingpondWeather/5
        public ActionResult TailingpondWeather(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            ViewData["id"] = id;
            DateTime now = DateTime.Now;

            Factory_daily_weather_info weatherInfo = factoryWeatherReposity.GetDailyWeatherInfo(id, now);
            if (weatherInfo == null)
            {
                weatherInfo = new Factory_daily_weather_info();
                weatherInfo.factory_id = id;
                weatherInfo.date = now.Date;
            }

            ViewData["success"] = false;
            return View(weatherInfo);
        }

        [HttpPost]
        public ActionResult TailingpondWeather(Factory_daily_weather_info weatherInfo)
        {
            ActionResult result = AllowForRole(RoleEnum.Recorder);
            if (result != null)
            {
                return result;
            }
            int id = weatherInfo.factory_id;
            ViewData["id"] = id;

            if (!CanEditTailingpond(id))
            {
                return RedirectToAction("Deny", "Home");
            }

            DateTime now = DateTime.Now;
            weatherInfo.date = now.Date;

            Factory_daily_weather_info oldWeatherInfo = factoryWeatherReposity.GetDailyWeatherInfo(id, now);
            if (oldWeatherInfo != null)
            {
                factoryWeatherReposity.DeleteDailyWeather(oldWeatherInfo);
            }
            factoryWeatherReposity.CreateDailyWeather(weatherInfo);
            ViewData["success"] = true;
            return View(weatherInfo);
        }

        private bool CanEditStack(int id)
        {
            bool result = false;
            User currentUser = (User)HttpContext.Session["currentUser"];

            if (currentUser.Factory.Stacks != null && currentUser.Factory.Stacks.Count > 0)
            {
                foreach (Stack stack in currentUser.Factory.Stacks)
                {
                    if (id == stack.Id)
                    {
                        result = true;
                        break;
                    }
                }
            }

            return result;
        }

        private bool CanEditTailingpond(int id)
        {
            bool result = false;
            User currentUser = (User)HttpContext.Session["currentUser"];

            if (currentUser.Factory.Tailingponds != null && currentUser.Factory.Tailingponds.Count > 0)
            {
                foreach (Tailingpond tailingpond in currentUser.Factory.Tailingponds)
                {
                    if (id == tailingpond.Id)
                    {
                        result = true;
                        break;
                    }
                }
            }

            return result;
        }
    }
}
